﻿// ***********************************************************************
// Apache 2.0 License
// Licensed under the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License. You may obtain
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY 
// IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR 
// PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing
// permissions and limitations under the License.
// ***********************************************************************
// Assembly  : ContractMeow.Api.Dtos
// File      : AttachmentJsonConverter.cs
//
// ***********************************************************************
using ContractMeow.Api.Dtos.Attachment;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;

namespace ContractMeow.Api.Dtos.Serialization
{
	internal class AttachmentJsonConverter : JsonConverter
	{
		private static readonly Type _GenericAttachmentType = typeof(Attachment.Attachment);

		public override Boolean CanRead { get { return true; } }
		public override Boolean CanWrite { get { return false; } }
		public override Boolean CanConvert(Type objectType)
		{
			return objectType == typeof(IAttachment[])
				   || objectType == typeof(IList<IAttachment>);
		}

		private static readonly Dictionary<String, Type> _TypeMap = new Dictionary<String, Type> {
			{ "image", typeof(ImageAttachment) },
			{ "file", typeof(FileAttachment) },
			{ "message", typeof(MessageAttachment) },
			{ "ymodule", typeof(YModuleAttachment) },
			{ "praise", typeof(PraiseAttachment) }
		};

		private Type GetTypeForItem(JToken item)
		{
			JToken type = item["type"];
			if (type != null)
			{
				var key = type.ToString();

				if (key == "ymodule")
				{
					JToken objectType = item["object_type"];
					if (objectType != null && objectType.ToString() == "page")
						return typeof(OpenGraphPageAttachment);

					JToken realType = item["real_type"];
					if (realType != null && realType.ToString() == "page")
						return typeof(NoteAttachment);

					return typeof(YModuleAttachment);
				}

				if (_TypeMap.ContainsKey(key))
					return _TypeMap[key];
			}

			return _GenericAttachmentType;
		}

		public override Object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
		{
			return JArray.Load(reader)
				.Select(item => serializer.Deserialize(item.CreateReader(), GetTypeForItem(item)))
				.Cast<IAttachment>()
				.ToArray();
		}

		public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
		{
			throw new NotImplementedException("This converter cannot write.");
		}
	}
}